package org.testis.testdriver.operations;

import org.testis.testdriver.*;
import org.testis.testdriver.AtofEnumaration.AtofLogLevel;
import org.testis.testdriver.AtofEnumaration.DebuggingMode;

/**
 * This class is the root operation class which helps logging of Started
 * execution information to database.
 * 
 * @author barisergun
 */
public class TestPartRootOperation implements TestPartOperations {

    private TestPart currentTestPart;

    public TestPartRootOperation(TestPart testPart) {
        currentTestPart = testPart;
    }

    public boolean runOperation(DebuggingMode mode) throws InterruptedException {

        String testPartParentGuid = "";
        Byte resByte = 0; // Test Part will be logged as false initially

        try {

            testPartParentGuid = currentTestPart.getParent().getPartGuid();
        } catch (NullPointerException ee) {

            testPartParentGuid = "-";
        }

        boolean logStartLog = true;
        boolean logOnceLogs = true;
        boolean logForStepContainers = false;

        StepContainer toCheck = null;
        if (currentTestPart instanceof StepContainer) {
            toCheck = (StepContainer) currentTestPart;
            if (toCheck.getTestCaseDataIndex() > 0) {
                logStartLog = false;
            }

        } else if (currentTestPart instanceof TestStep) {

            if (((TestStep) currentTestPart).getRetryCount() > 0) {
                logOnceLogs = false;
            }

            /*if (((StepContainer) currentTestPart.getParent()).
            getTestCaseDataIndex() > 1) {
            logStartLog = false;
            }*/
        }

        if (logStartLog) {
            String partName = currentTestPart.getPartName();
            String partGuid = currentTestPart.getPartGuid();
            String partNameForStepContainers = currentTestPart.getPartName();
            String partGuidForStepContainers = currentTestPart.getPartGuid();

            if (currentTestPart instanceof TestStep) {



                if (currentTestPart.getParent().getContainerType()
                        == AtofEnumaration.TestPartType.TestStepGroup) {

                    testPartParentGuid = currentTestPart.getParent().getPartGuid()
                            + currentTestPart.getParent().getParent().
                            getPartGuidLongFromChild().
                            replaceAll(currentTestPart.getParent().getParent().
                            getPartGuid(),
                            "")
                            + currentTestPart.getPartGuidLongFromChild().replaceAll(
                            currentTestPart.getPartGuid(),
                            "");

                    partName = currentTestPart.getPartName();
                    partGuid = currentTestPart.getPartGuidLongFromChild()
                            + currentTestPart.getParent().getParent().
                            getPartGuidLongFromChild().
                            replaceAll(currentTestPart.getParent().getParent().
                            getPartGuid(),
                            "");

                    partNameForStepContainers = partName;
                    partGuidForStepContainers = partGuid;

                } else {
                    testPartParentGuid = currentTestPart.getParent().getPartGuid()
                            + currentTestPart.getPartGuidLongFromChild().replaceAll(
                            currentTestPart.getPartGuid(),
                            "");


                    partName = currentTestPart.getPartName();
                    partGuid = currentTestPart.getPartGuidLongFromChild();
                    partNameForStepContainers = partName;
                    partGuidForStepContainers = partGuid;
                }

            } else if (currentTestPart instanceof StepContainer) {



                if (currentTestPart.getContainerType()
                        == AtofEnumaration.TestPartType.TestCase || currentTestPart.getContainerType()
                        == AtofEnumaration.TestPartType.PreConditionCase || currentTestPart.getContainerType()
                        == AtofEnumaration.TestPartType.PostConditionCase) {
                    logForStepContainers = true;
                    partNameForStepContainers =
                            currentTestPart.getPartNameLongFromChild();
                    partGuidForStepContainers =
                            currentTestPart.getPartGuidLongFromChild();


                } else if (currentTestPart.getContainerType()
                        == AtofEnumaration.TestPartType.TestStepGroup) {
                    logForStepContainers = true;

                    testPartParentGuid = currentTestPart.getParent().
                            getPartGuidLongFromChild();

                    partName = currentTestPart.getPartName();// Test Case Invocation
                    // Count and Data Count information are useless in the partName
                    // but necessary in the partGuid for uniqueness of logs. Because
                    // Test Step Group will have more than one invcations and Datas.


                    partGuid = currentTestPart.getPartGuid() + currentTestPart.getParent().
                            getPartGuidLongFromChild().replaceAll(currentTestPart.getParent().
                            getPartGuid(),
                            "");
                    partNameForStepContainers = currentTestPart.getPartName() + currentTestPart.getParent().
                            getPartNameLongFromChild().replace(currentTestPart.getParent().
                            getPartName(),
                            "");
                    partGuidForStepContainers = currentTestPart.getPartGuid()
                            + currentTestPart.getPartGuidLongFromChild().
                            replaceAll(
                            currentTestPart.getPartGuid(),
                            "") + currentTestPart.getParent().
                            getPartGuidLongFromChild().replaceAll(currentTestPart.getParent().
                            getPartGuid(),
                            "");

                }

            }

            if (logForStepContainers) {
                if (!currentTestPart.getTestPartList().isEmpty()) {

                    // No need to log the invocation count detail if there is no
                    // child of the Step Container.
                    NotificationSubjectSingleton.getInstance().notifyLogHeaderMessages(
                            Integer.parseInt(currentTestPart.getPartId()),
                            currentTestPart.getContainerType().
                            ordinal(),
                            resByte,
                            partGuid, // Parent part Guid
                            partNameForStepContainers,
                            partGuidForStepContainers,
                            ExecutionGuidProvider.createInstance().
                            getExistingExecId());

                    NotificationSubjectSingleton.getInstance().notifyLogMessages(partNameForStepContainers,
                            AtofLogLevel.INFO,
                            "Started execution.",
                            partGuidForStepContainers);
                }
            }
            NotificationSubjectSingleton.getInstance().notifyLogHeaderMessages(
                    Integer.parseInt(currentTestPart.getPartId()),
                    currentTestPart.getContainerType().
                    ordinal(),
                    resByte,
                    testPartParentGuid, // Parent part Guid
                    partName,
                    partGuid,
                    ExecutionGuidProvider.createInstance().
                    getExistingExecId());

            if (currentTestPart instanceof StepContainer) {
                if (!currentTestPart.getTestPartList().isEmpty()) {
                    NotificationSubjectSingleton.getInstance().notifyLogMessages(
                            partName,
                            AtofLogLevel.INFO,
                            "Started execution.",
                            partGuid);
                }
            }
            if (logOnceLogs) {
                NotificationSubjectSingleton.getInstance().notifyLogMessages(
                        partName,
                        AtofLogLevel.DESC,
                        currentTestPart.getPartDescription(),
                        partGuid);
            }





        }



        return true;
    }
}
